//用户管理实现
#include "user_manager.h"
#include <fstream>
#include <nlohmann/json.hpp> // 需引入nlohmann/json库（Windows需配置依赖）
#include <openssl/sha.h>
#include <chrono>
#include <iostream>

using json = nlohmann::json;

// 加载用户配置（JSON格式：[{"username":"admin", "password_hash":"...", "role":1, "perm_mask":4294967295, ...}]）
bool UserManager::loadUsers(const std::string& config_path) {
    std::ifstream ifs(config_path);
    if (!ifs.is_open()) {
        // 配置文件不存在，创建默认用户（admin/Admin@123）
        User default_admin;
        default_admin.username = "admin";
        default_admin.password_hash = hashPassword("Admin@123");
        default_admin.role = 0x01; // 管理员
        default_admin.perm_mask = 0xFFFFFFFF; // 全权限
        default_admin.is_locked = false;
        default_admin.login_attempts = 0;
        users_.push_back(std::make_shared<User>(default_admin));

        // 保存默认用户到配置文件
        return saveUsers(config_path);
    }

    // 解析JSON文件
    json j;
    try {
        ifs >> j;
        for (auto& item : j) {
            auto user = std::make_shared<User>();
            user->username = item["username"].get<std::string>();
            user->password_hash = item["password_hash"].get<std::string>();
            user->role = item["role"].get<uint8_t>();
            user->perm_mask = item["perm_mask"].get<uint32_t>();
            user->is_locked = item["is_locked"].get<bool>();
            user->login_attempts = item["login_attempts"].get<int>();
            user->lock_time = item["lock_time"].get<uint64_t>();
            users_.push_back(user);
        }
    } catch (const json::exception& e) {
        std::cerr << "解析用户配置失败：" << e.what() << std::endl;
        return false;
    }

    return true;
}

// 保存用户配置到JSON文件
bool UserManager::saveUsers(const std::string& config_path) {
    json j = json::array();
    for (auto& user : users_) {
        json item;
        item["username"] = user->username;
        item["password_hash"] = user->password_hash;
        item["role"] = user->role;
        item["perm_mask"] = user->perm_mask;
        item["is_locked"] = user->is_locked;
        item["login_attempts"] = user->login_attempts;
        item["lock_time"] = user->lock_time;
        j.push_back(item);
    }

    std::ofstream ofs(config_path);
    if (!ofs.is_open()) {
        std::cerr << "保存用户配置失败：无法打开文件" << std::endl;
        return false;
    }

    ofs << std::setw(4) << j << std::endl;
    return true;
}

// 用户登录
bool UserManager::login(const std::string& username, const std::string& password, std::string& err_msg) {
    // 1. 解锁过期用户
    unlockExpiredUsers();

    // 2. 查找用户
    auto it = std::find_if(users_.begin(), users_.end(), 
        [&username](const std::shared_ptr<User>& user) {
            return user->username == username;
        });
    if (it == users_.end()) {
        err_msg = "无效用户名";
        return false;
    }
    auto user = *it;

    // 3. 检查用户是否锁定
    if (user->is_locked) {
        uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count();
        uint64_t remaining = (user->lock_time + LOCK_DURATION) - now;
        if (remaining > 0) {
            err_msg = "用户已锁定，剩余" + std::to_string(remaining / 1000) + "秒";
            return false;
        } else {
            // 锁定时间过期，解锁
            user->is_locked = false;
            user->login_attempts = 0;
        }
    }

    // 4. 校验密码
    std::string password_hash = hashPassword(password);
    if (user->password_hash != password_hash) {
        user->login_attempts++;
        if (user->login_attempts >= MAX_LOGIN_ATTEMPTS) {
            user->is_locked = true;
            user->lock_time = std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::system_clock::now().time_since_epoch()).count();
            err_msg = "密码错误，用户已锁定（5次失败）";
        } else {
            err_msg = "密码错误，剩余" + std::to_string(MAX_LOGIN_ATTEMPTS - user->login_attempts) + "次机会";
        }
        return false;
    }

    // 5. 登录成功，重置失败次数
    user->login_attempts = 0;
    current_user_ = user;
    err_msg = "登录成功";
    return true;
}

// 用户登出
void UserManager::logout() {
    current_user_.reset();
}

// 获取当前登录用户
std::shared_ptr<User> UserManager::getCurrentUser() const {
    return current_user_;
}

// 添加用户（仅管理员可操作，此处简化：未校验当前用户权限，实际需在调用处校验）
bool UserManager::addUser(const User& user, std::string& err_msg) {
    // 检查用户名是否已存在
    auto it = std::find_if(users_.begin(), users_.end(), 
        [&user](const std::shared_ptr<User>& u) {
            return u->username == user.username;
        });
    if (it != users_.end()) {
        err_msg = "用户名已存在";
        return false;
    }

    // 添加新用户（密码需哈希，避免明文）
    auto new_user = std::make_shared<User>(user);
    new_user->password_hash = hashPassword(user.password_hash); // 传入的是明文密码，需哈希
    new_user->is_locked = false;
    new_user->login_attempts = 0;
    new_user->lock_time = 0;
    users_.push_back(new_user);

    err_msg = "用户添加成功";
    return true;
}

// 删除用户（仅管理员可操作）
bool UserManager::deleteUser(const std::string& username, std::string& err_msg) {
    // 禁止删除当前登录用户
    if (current_user_ && current_user_->username == username) {
        err_msg = "无法删除当前登录用户";
        return false;
    }

    // 查找并删除用户
    auto it = std::find_if(users_.begin(), users_.end(), 
        [&username](const std::shared_ptr<User>& user) {
            return user->username == username;
        });
    if (it == users_.end()) {
        err_msg = "用户不存在";
        return false;
    }

    users_.erase(it);
    err_msg = "用户删除成功";
    return true;
}

// 修改用户权限
bool UserManager::modifyUserPerm(const std::string& username, uint32_t new_perm_mask, std::string& err_msg) {
    auto it = std::find_if(users_.begin(), users_.end(), 
        [&username](const std::shared_ptr<User>& user) {
            return user->username == username;
        });
    if (it == users_.end()) {
        err_msg = "用户不存在";
        return false;
    }

    (*it)->perm_mask = new_perm_mask;
    err_msg = "用户权限修改成功";
    return true;
}

// 密码哈希（SHA256 + 盐值，此处简化：盐值固定为"robot_system_salt"，实际应每个用户不同盐值）
std::string UserManager::hashPassword(const std::string& password) {
    std::string salt = "robot_system_salt";
    std::string data = password + salt;

    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX ctx;
    SHA256_Init(&ctx);
    SHA256_Update(&ctx, data.c_str(), data.size());
    SHA256_Final(hash, &ctx);

    // 转换为十六进制字符串
    std::string hash_str;
    char buf[3];
    for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
        sprintf(buf, "%02x", hash[i]);
        hash_str += buf;
    }

    return hash_str;
}

// 检查用户是否锁定
bool UserManager::isUserLocked(const std::string& username) {
    auto it = std::find_if(users_.begin(), users_.end(), 
        [&username](const std::shared_ptr<User>& user) {
            return user->username == username;
        });
    if (it == users_.end()) return false;

    if (!(*it)->is_locked) return false;

    // 检查锁定是否过期
    uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();
    return (now - (*it)->lock_time) < LOCK_DURATION;
}

// 解锁过期用户
void UserManager::unlockExpiredUsers() {
    uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();

    for (auto& user : users_) {
        if (user->is_locked && (now - user->lock_time) >= LOCK_DURATION) {
            user->is_locked = false;
            user->login_attempts = 0;
        }
    }
}